#ifndef FIRMWAREUPGRADER_H
#define FIRMWAREUPGRADER_H

#include <QObject>
#include <QByteArray>
#include <QTimer>

#define PACKET_SIZE 256

class FirmwareUpgrader : public QObject {
    Q_OBJECT

public:
    explicit FirmwareUpgrader(QObject *parent = nullptr);
    void startUpgrade(const QString &filePath, quint8 deviceAddress); // Update method signature
    void stopUpgrade(); // Method to stop the upgrade process
    void sendPacket(int sequenceNumber);
    void handleResponse();
    void parseSerialData(const QByteArray &data);
    int getFirmwareSize() const { return m_firmwareSize; }
    void setAckRequired(bool ackRequired) { m_ackRequired = ackRequired; }
    void sendSoftResetCommand(); // Method to send MCU soft reset command
    void sendUpgradeStateMachineResetCommand(); // Method to send MCU firmware upgrade state machine reset command
    void setDeviceAddress(quint8 address) { m_deviceAddress = address; } // Method to set device address

signals:
    void progressUpdated(int value);
    void upgradeCompleted();
    void upgradeFailed();
    void sendData(const QByteArray &data);
    void crcCalculated(quint16 crc); // Signal for CRC calculation

private slots:
    void onRespondTimeout();

private:
    QByteArray m_firmwareData;
    int m_sequenceNumber;
    int m_firmwareSize;
    int m_totalSequence;
    int m_retryCount;
    QTimer m_retryTimer;
    const int RETRY_INTERVAL_MS = 1000; // 1 second retry interval
    quint16 calculateCRC16(const QByteArray &data);
    quint16 calculateChecksum(const QByteArray &data);
    void sendQueryPacket();
    QByteArray creatorPack(quint8 address, quint8 cmd, QByteArray data);
    bool m_ackRequired;
    bool m_isUpgrading; // Flag to indicate if the upgrade is in progress
    void clearUpgrader(); // Method to clear all attributes and variables
    quint8 m_deviceAddress; // Store device address
    quint8 parseProtocolData(const QByteArray &data); // Method to parse protocol data
};

#endif // FIRMWAREUPGRADER_H
